#ifndef __REGACC_H__
#define __REGACC_H__

// will go through dcapi interface
extern int mapped_io_base_addr;

#define __VOLATILE

#if 1
#define REG_ADDRESS(a, b) (a + b)
#else
extern void break_on_bad_base_address(int offset);
static int REG_ADDRESS(int a, int b) 
{
	if (!a)
		break_on_bad_base_address(b);
	return a + b;
}
#endif

#if 0
#define dcreg(a)    (*(__VOLATILE UINT8 *)(REG_ADDRESS(mapped_io_base_addr, a)))
#define regrd(a, d) ((*(d)) = *(__VOLATILE UINT8 *)(REG_ADDRESS(mapped_io_base_addr, a)))
#define regwr(a, d) *(__VOLATILE UINT8 *)(REG_ADDRESS(mapped_io_base_addr, a)) = (unsigned char)d

#define dcreg16(a)    (*(__VOLATILE UINT16 *)(REG_ADDRESS(mapped_io_base_addr, a)))
#define regrd16(a, d) ((*(d)) = *(__VOLATILE UINT16 *)(REG_ADDRESS(mapped_io_base_addr, a)))
#define regwr16(a, d) *(__VOLATILE UINT16 *)(REG_ADDRESS(mapped_io_base_addr, a)) = ((unsigned short)d)

#define dcreg32(a)    (*(__VOLATILE UINT32 *)(REG_ADDRESS(mapped_io_base_addr, a)))
#define regrd32(a, d) ((*(d)) = *(__VOLATILE UINT32 *)(REG_ADDRESS(mapped_io_base_addr, a)))
#define regwr32(a, d) *(__VOLATILE UINT32 *)(REG_ADDRESS(mapped_io_base_addr, a)) = ((unsigned long)d)

#else

//#undef	RADEF_DCREG_BASE
//#define	RADEF_DCREG_BASE	mapped_io_base_addr
#define	RA_MAX_BYTE_ACCESS	0x3ffff

#if (OA_CHIPID == 10) || (OA_CHIPID == 12)

PORTABLE_INLINE UINT32 dcregw16( UINT32 a, UINT16 d )
{
    if (a > RA_MAX_BYTE_ACCESS)
        return ((*((volatile UINT32 *)(mapped_io_base_addr+(a))))=(d));
    else
        return ((*((volatile UINT16 *)(mapped_io_base_addr+(a))))=(d));
}

PORTABLE_INLINE UINT32 dcregw( UINT32 a, UINT8 d )
{
    if (a > RA_MAX_BYTE_ACCESS)
        return ((*((volatile UINT32 *)(mapped_io_base_addr+(a))))=(d));
    else
        return ((*((volatile UINT8 *)(mapped_io_base_addr+(a))))=(d));
}

PORTABLE_INLINE UINT32 dcregwOR16( UINT32 a, UINT16 d )
{
    if (a > RA_MAX_BYTE_ACCESS)
        return ((*((volatile UINT32 *)(mapped_io_base_addr+(a))))|=(d));
    else
        return ((*((volatile UINT16 *)(mapped_io_base_addr+(a))))|=(d));
}

PORTABLE_INLINE UINT32 dcregwOR( UINT32 a, UINT8 d )
{
    if (a > RA_MAX_BYTE_ACCESS)
        return ((*((volatile UINT32 *)(mapped_io_base_addr+(a))))|=(d));
    else
        return ((*((volatile UINT8  *)(mapped_io_base_addr+(a))))|=(d));
}

PORTABLE_INLINE UINT32 dcregwAND16( UINT32 a, UINT16 d )
{
    if (a > RA_MAX_BYTE_ACCESS)
        return ((*((volatile UINT32 *)(mapped_io_base_addr+(a))))&=(d));
    else
        return ((*((volatile UINT16 *)(mapped_io_base_addr+(a))))&=(d));
}

PORTABLE_INLINE UINT32 dcregwAND( UINT32 a, UINT8 d )
{
    if (a > RA_MAX_BYTE_ACCESS)
        return ((*((volatile UINT32 *)(mapped_io_base_addr+(a))))&=(d));
    else
        return ((*((volatile UINT8  *)(mapped_io_base_addr+(a))))&=(d));
}

# define dcreg(a)    ((a > RA_MAX_BYTE_ACCESS) ? (*((volatile UINT32 *)(mapped_io_base_addr+(a)))) : \
                                                 (*((volatile UINT8 *)(mapped_io_base_addr+(a)))))

# define regrd(a, d) ((a > RA_MAX_BYTE_ACCESS) ? ((*(d))=(*((volatile UINT32 *)(mapped_io_base_addr+(a))))) :\
                                                 ((*(d))=(*((volatile UINT8 *)(mapped_io_base_addr+(a))))))

# define regwr(a, d) ((a > RA_MAX_BYTE_ACCESS) ? ((*((volatile UINT32 *)(mapped_io_base_addr+(a))))=(d)) :\
                                                 ((*((volatile UINT8 *)(mapped_io_base_addr+(a))))=(d)))

# define dcreg16(a)    ((a > RA_MAX_BYTE_ACCESS) ? (*((volatile UINT32 *)(mapped_io_base_addr+(a)))) :\
                                                   (*((volatile UINT16 *)(mapped_io_base_addr+(a)))))

# define regrd16(a, d) ((a > RA_MAX_BYTE_ACCESS) ? ((*(d))=(*((volatile UINT32 *)(mapped_io_base_addr+(a))))) :\
                                                   ((*(d))=(*((volatile UINT16 *)(mapped_io_base_addr+(a))))))

# define regwr16(a, d) ((a > RA_MAX_BYTE_ACCESS) ? ((*((volatile UINT32 *)(mapped_io_base_addr+(a))))=(d)) :\
                                                   ((*((volatile UINT16 *)(mapped_io_base_addr+(a))))=(d)))

#else
#pragma message ("NONE GREYLOCK")
#define dcregw16( a, d ) ((*((volatile UINT16 *)(mapped_io_base_addr+(a))))=(d))
#define dcregw( a, d ) ((*((volatile UINT8 *)(mapped_io_base_addr+(a))))=(d))
#define dcregwOR16( a, d ) ((*((volatile UINT16 *)(mapped_io_base_addr+(a))))|=(d))
#define dcregwOR( a, d ) ((*((volatile UINT8  *)(mapped_io_base_addr+(a))))|=(d))
#define dcregwAND16( a, d ) ((*((volatile UINT16 *)(mapped_io_base_addr+(a))))&=(d))
#define dcregwAND( a, d ) ((*((volatile UINT8  *)(mapped_io_base_addr+(a))))&=(d))

#define dcreg(a)    (*(volatile UINT8 *)(mapped_io_base_addr + a))
# define regrd(a, d) ((*(d))=(*((volatile UINT8 *)(mapped_io_base_addr+(a)))))
# define regwr(a, d) ((*((volatile UINT8 *)(mapped_io_base_addr+(a))))=(d))

# define dcreg16(a)    (*((volatile UINT16 *)(mapped_io_base_addr+(a))))
# define regrd16(a, d) ((*(d))=(*((volatile UINT16 *)(mapped_io_base_addr+(a)))))
# define regwr16(a, d) ((*((volatile UINT16 *)(mapped_io_base_addr+(a))))=(d))

#endif

# define dcreg32(a)    (*((volatile UINT32 *)(mapped_io_base_addr+(a))))
# define regrd32(a, d) ((*(d))=(*((volatile UINT32 *)(mapped_io_base_addr+(a)))))
# define regwr32(a, d) ((*((volatile UINT32 *)(mapped_io_base_addr+(a))))=(d))
#endif

#endif
